package com.link.base.base.wechat.service;

import com.link.base.base.wechat.dao.mybatis.mapper.WxImageMapper;
import com.link.base.base.wechat.dao.mybatis.mapper.WxMediaMapper;
import com.link.base.base.wechat.model.WxImage;
import com.link.base.base.wechat.model.WxMedia;
import com.link.base.wechat.mpnews.model.Article;
import com.link.base.wechat.mpnews.service.ArticleService;
import com.link.base.wechat.wxplatform.model.WxPlatform;
import com.link.base.wechat.wxplatform.service.WxPlatformService;
import com.link.core.basic.dao.KeyGenerateDao;
import com.link.core.basic.dao.mapper.BasicMapper;
import com.link.core.basic.service.BasicServiceException;
import com.link.core.basic.service.BasicServiceImpl;
import com.link.core.util.DateUtil;
import com.link.core.util.StringUtils;
import com.link.core.util.UserUtil;
import com.link.base.core.basic.util.YmlConstants;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * WxMedia-微信素材中间表
 *
 * @author 路江
 * @date 2019/05/22 10:12
 */
@Service
public class WxMediaServiceImpl extends BasicServiceImpl<WxMedia> implements WxMediaService {

    @Resource
    private WxMediaMapper wxMediaMapper;

    @Resource
    private WxPlatformService wxPlatformService;

    @Resource
    private WxImageService wxImageService;

    @Resource
    private WxImageMapper wxImageMapper;

    @Resource
    private ArticleService articleService;

    @Resource
    private ArticlesService articlesService;

    @Resource
    private KeyGenerateDao keyGenerateDao;

    @Override
    public BasicMapper<WxMedia> getBasicMapper() {
        return wxMediaMapper;
    }

    /**
     * 微信素材保存
     *
     * @author lujiang
     * @date 2019-05-22
     * @param articleList 图文素材对象
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = BasicServiceException.class)
    public Map<String, Object> saveAndSendArticle(List<Article> articleList) throws Exception {
        Map<String,Object> result = new HashMap<>(8);
        Article articles = new Article();
        if  (articleList.size() > 0) {
            articles = articleList.get(0);
        }
        String groupId = "";
        if (articles.getGroupId() == null) {
            // 获取图文组id
            groupId = String.valueOf(keyGenerateDao.keyGenerate());
            for (int i = 0;i < articleList.size();i++) {
                Article a = articleList.get(i);
                a.setGroupId(groupId);
                a.setIndex(i);
                if (a.getWxIds() != null && a.getWxIds().size() > 0) {
                    a.setWxId(a.getWxIds().get(0));
                }
                articlesService.insert(a);
            }
        } else if (!StringUtils.equals(articles.getRow_status(),"UPDATE")) {
            groupId = articles.getGroupId();
            List<Long> wxIds = articles.getWxIds();
            List<String> appIds = articles.getAppIds();
            Article article = new Article();
            article.setGroupId(groupId);
            article.setPageFlag(false);
            articleList = articlesService.queryByGroupId(article);
            if (articleList.size() > 0) {
                articles = articleList.get(0);
                articles.setWxIds(wxIds);
                articles.setAppIds(appIds);
            }
        } else if (StringUtils.equals(articles.getRow_status(),"UPDATE")) {
            for (int i = 0;i < articleList.size();i++) {
                Article a = articleList.get(i);
                a.setIndex(a.getMediaIndex());
                groupId = articles.getGroupId();
                articlesService.update(a);
            }
        }
        // 上传素材（图片，图文）
        List<WxMedia> list = saveArticle(articles,articleList,groupId);
        result.put("rows",list);
        result.put("groupId",groupId);
        return result;
    }

    /**
     * 上传素材（图片，图文）
     *
     * @author 路江
     * @date 2019-05-22
     * @param articles 第一篇图文
     * @param articleList 全部图文对象
     * @param groupId 图文分组id
     * @return
     * @throws Exception
     */
    private List<WxMedia> saveArticle(Article articles, List<Article> articleList, String groupId) throws Exception {
        List<WxMedia> list = new ArrayList<>();
        // 当前时间
        String nowTime = DateUtil.dateToStr(new Date(),"yyyy-MM-dd hh:mm:ss");
        for (Article article : articleList) {
            article.setThumbMediaIdCopy(Long.parseLong(article.getThumbMediaId()));
        }
        if (articles.getWxIds() != null) {
            for (Long wxId : articles.getWxIds()) {
                WxPlatform wxPlatform = wxPlatformService.queryById(wxId);
                for (Article article : articleList) {
                    // 正文内图片处理
                    article = uploadContentImage(article,wxPlatform.getWx_app_id(),nowTime);
                    //判断此图片之前是否上传过 ,mediaId 和 wxId 确定唯一性
                    WxMedia wxImageMedia = new WxMedia();
                    wxImageMedia.setMediaId(article.getThumbMediaIdCopy());
                    wxImageMedia.setWxId(wxPlatform.getWx_app_id());
                    List<WxMedia> mediaList = wxMediaMapper.queryByExamplePage(wxImageMedia);
                    // 生成图片—公众号中间表记录
                    WxMedia wxMedia = new WxMedia();
                    if (mediaList.size() > 0) {
                        wxMedia.setWxMediaId(mediaList.get(0).getWxMediaId());
                        wxMedia.setWxUrl(mediaList.get(0).getWxUrl());
                    } else {
                        // 上传图片
                        WxImage wxImage = new WxImage();
                        wxImage.setId(article.getThumbMediaIdCopy());
                        wxImage = wxImageService.queryById(wxImage);
                        String imgUrl = YmlConstants.getPortalShareFileDir() + wxImage.getAttUrl();
                        // 查询appid
                        Map<String,Object> imageMap = articleService.uploadMaterial(wxPlatform.getWx_app_id(),"image",imgUrl);
                        if (null == imageMap || imageMap.get("result") == null || StringUtils.equals("0",imageMap.get("result").toString())) {
                            throw new BasicServiceException("图片上传失败");
                        }
                        wxMedia.setWxMediaId(imageMap.get("media_id").toString());
                        wxMedia.setWxUrl(imageMap.get("url").toString());
                        wxMedia.setMediaId(article.getThumbMediaIdCopy());
                        wxMedia.setMediaType("Image");
                        wxMedia.setWxId(wxPlatform.getWx_app_id());
                        wxMedia.setSyncStatus("Succeeded");
                        wxMedia.setSyncTime(nowTime);
                        wxMedia.setSyncComment("ok");
                        // 图片附件id
                        this.insert(wxMedia);
                    }
                    // 设置图文素材中图片素材id
                    article.setThumbMediaId(wxMedia.getWxMediaId());
                    article.setWxId(wxPlatform.getId());
                    article.setAppId(wxPlatform.getWx_app_id());
                }
                // 新增图文素材
                WxMedia articleMedia = new WxMedia();
                articleMedia.setMediaId(Long.parseLong(groupId));
                articleMedia.setWxId(wxPlatform.getWx_app_id());
                List<WxMedia> articleMediaList = wxMediaMapper.queryByExamplePage(articleMedia);
                // 生成图文—公众号中间表记录
                WxMedia wxArticleMedia = new WxMedia();
                if (articleMediaList.size() > 0) {
                    wxArticleMedia = articleMediaList.get(0);
                    if (StringUtils.equals(articles.getRow_status(),"UPDATE")) {
                        for (Article article : articleList) {
                            article.setMediaId(wxArticleMedia.getWxMediaId());
                        }
                        Map<String, Object> articleMap = articleService.updateArticles(wxPlatform.getWx_app_id(),articleList);
                        if (null == articleMap || StringUtils.equals("0",articleMap.get("result").toString())) {
                            throw new BasicServiceException("图文修改失败");
                        }
                    }
                } else {
                    // 上传图文
                    Map<String, Object> articleMap = articleService.uploadArticles(wxPlatform.getWx_app_id(),articleList);
                    if (null == articleMap || StringUtils.equals("0",articleMap.get("result").toString())) {
                        throw new BasicServiceException("图文上传失败");
                    }
                    wxArticleMedia.setWxMediaId(articleMap.get("jsonObject").toString());
                    wxArticleMedia.setMediaType("Article");
                    wxArticleMedia.setWxId(wxPlatform.getWx_app_id());
                    wxArticleMedia.setSyncStatus("Succeeded");
                    wxArticleMedia.setSyncTime(nowTime);
                    wxArticleMedia.setSyncComment("ok");
                    // 图文分组id
                    wxArticleMedia.setMediaId(Long.parseLong(groupId));
                    this.insert(wxArticleMedia);
                }
                list.add(wxArticleMedia);
            }
        }
        return list;
    }

    /**
     * 将正文内图片拿出上图片
     *
     * @author lujiang
     * @date 2019-06-03
     * @param article
     * @return
     * @throws Exception
     */
    private Article uploadContentImage(Article article, String wxId, String nowTime) throws Exception {
        // 查询出所有图片集合
        List<String> list = new ArrayList<>();
        String content = article.getContent();
        Pattern p_img = Pattern.compile("<(img|IMG)(.*?)(/>|></img>|>)");
        Matcher m_img = p_img.matcher(content);
        boolean result_img = m_img.find();
        if (result_img) {
            while (result_img) {
                String str_img = m_img.group(2);
                Pattern p_src = Pattern.compile("(src|SRC)=(\"|\')(.*?)(\"|\')");
                Matcher m_src = p_src.matcher(str_img);
                if (m_src.find()) {
                    String str_src = m_src.group(3);
                    list.add(str_src);
                    content = content.replace("img" + str_img,"xxx");
                    m_img = p_img.matcher(content);
                    result_img = m_img.find();
                }
            }
        }
        // 未上传的图片进行上传
        List<String> wxUrllist = new ArrayList<String>();
        for (int i = 0;i < list.size();i++) {
            String imageUrl = list.get(i);
            String u = "";
            String wxUrl = "";
            String webUrl = "";
            if (imageUrl.contains("/web")) {
                u = list.get(i).substring(list.get(i).indexOf("/web"));
            } else if (imageUrl.contains("/picture")) {
                u = list.get(i).substring(list.get(i).indexOf("/picture"));
            } else if (imageUrl.contains("mmbiz.qpic.cn")) {
                wxUrl = imageUrl;
            } else if (imageUrl.contains("https://")) {
                webUrl = imageUrl;
            } else {
                throw new BasicServiceException("图片上传失败");
            }
            if (StringUtils.isNotBlank(wxUrl)) {
                wxUrllist.add(wxUrl);
                continue;
            }
            if (StringUtils.isNotBlank(webUrl)) {
                Map<String,Object> imageMap = articleService.uploadMaterial(wxId,"image",download(webUrl));
                if (null == imageMap || imageMap.get("result") == null || StringUtils.equals("0",imageMap.get("result").toString())) {
                    throw new BasicServiceException("图片上传失败");
                }
                wxUrllist.add(imageMap.get("url").toString());
                continue;
            }
            WxImage wxImage = new WxImage();
            wxImage.setTempMaterialUrl("%" + u);
            wxImage = wxImageMapper.querybyUrl(wxImage);
            if (wxImage != null && StringUtils.isNotBlank(wxImage.getAttUrl())) {
                wxUrllist.add(wxImage.getAttUrl());
            } else if (wxImage == null) {
                WxImage image = new WxImage();
                image.setTempMaterialUrl("%" + u);
                image = wxImageMapper.queryByImage(image);
                // 上传图片到服务器
                String imgUrl = YmlConstants.getPortalShareFileDir() + u;
                Map<String,Object> imageMap = articleService.uploadMaterial(wxId,"image",imgUrl);
                if (null == imageMap || imageMap.get("result") == null || StringUtils.equals("0",imageMap.get("result").toString())) {
                    throw new BasicServiceException("图片上传失败");
                }
                WxMedia wxMedia = new WxMedia();
                wxMedia.setWxMediaId(imageMap.get("media_id").toString());
                wxMedia.setWxUrl(imageMap.get("url").toString());
                if (image != null) {
                    wxMedia.setMediaId(image.getId());
                }
                wxMedia.setMediaType("Image");
                wxMedia.setWxId(wxId);
                wxMedia.setSyncStatus("Succeeded");
                wxMedia.setSyncTime(nowTime);
                wxMedia.setSyncComment("ok");
                // 图片附件id
                this.insert(wxMedia);
                wxUrllist.add(imageMap.get("url").toString());
            }
        }
        for (int i = 0;i < wxUrllist.size();i++) {
            article.setContent(article.getContent().replace(list.get(i),wxUrllist.get(i)));
        }
        return article;
    }

    @Override
    public WxMedia queryByMediaId(WxMedia wxMedia) throws Exception {
        return wxMediaMapper.queryByMediaId(wxMedia);
    }

    /**
     * 将网络图片下载到服务器在上传
     *
     * @param uri
     * @return
     * @throws Exception
     */
    private String download(String uri) throws Exception {
        String picpath = "";
        InputStream is = null;
        OutputStream os = null;
        try {
            // 构造URL
            URL url = new URL(uri);
            // 打开连接
            URLConnection con = url.openConnection();
            // 设置请求超时为5s
            con.setConnectTimeout(5 * 1000);
            // 输入流
            is = con.getInputStream();
            // 1K的数据缓冲
            byte[] bs = new byte[1024];
            // 读取到的数据长度
            int len;
            String path = YmlConstants.getPortalShareFileDir() + "/web/file/wxmedia/000/" + UserUtil.getUser().getId() + "/";
            // 输出的文件流
            File sf = new File(path);
            if (!sf.exists()) {
                sf.mkdirs();
            }
            picpath = path + DateUtil.dateToStr(new Date(), "yyyyMMddHHmmss") + ".png";
            os = new FileOutputStream(picpath);
            // 开始读取
            while ((len = is.read(bs)) != -1) {
                os.write(bs, 0, len);
            }
            // 完毕，关闭所有链接
            os.close();
            is.close();
        } catch (IOException e) {
            throw new BasicServiceException(e.getMessage());
        } finally {
            if (null != os) {
                os.close();
            }
            if (null != is) {
                is.close();
            }
        }
        return picpath;
    }

}

